#include "method_inspect.h"

namespace abccontext
{
    std::shared_ptr<AbcNode<AbckitCoreModule>> GetMethodModuleNode(std::shared_ptr<AbcFunc> method)
    {
        if (method->parentModule)
        {
            return method->parentModule;
        }
        if (method->parentNamespace)
        {
            return method->parentNamespace->parentModule;
        }
        if (method->parentClass)
        {
            return method->parentClass->parentModule;
        }
        std::shared_ptr<AbcNode<AbckitCoreModule>> emptyPtr;
        return emptyPtr;
    }

    std::shared_ptr<AbcNode<AbckitCoreNamespace>> GetMethodNamespaceNode(std::shared_ptr<AbcFunc> method)
    {
        if (method->parentNamespace)
        {
            return method->parentNamespace;
        }

        if (method->parentClass && method->parentClass->parentNS)
        {
            return method->parentClass->parentNS;
        }
        std::shared_ptr<AbcNode<AbckitCoreNamespace>> emptyPtr;
        return emptyPtr;
    }

    std::shared_ptr<AbcNode<AbckitCoreClass>> GetMethodClassNode(std::shared_ptr<AbcFunc> method)
    {
        if (method->parentClass)
        {
            return method->parentClass;
        }
        std::shared_ptr<AbcNode<AbckitCoreClass>> emptyPtr;
        return emptyPtr;
    }

    std::shared_ptr<AbcPath> GetPath(std::shared_ptr<AbcFunc> method)
    {
        if (method->parentClass)
        {
            return method->parentClass->path;
        }

        if (method->parentNamespace)
        {
            return method->parentNamespace->path;
        }
        if (method->parentModule)
        {
            return method->parentModule->path;
        }
        std::shared_ptr<AbcPath> emptyPath;
        return emptyPath;
    }
    std::string GetMethodName(std::shared_ptr<AbcFunc> method)
    {
        return method->name;
    }

    std::string GetClassName(std::shared_ptr<AbcFunc> method)
    {
        auto classNode = GetMethodClassNode(method);
        if (classNode)
        {
            return classNode->name;
        }
        return "";
    }
    std::string GetNamespacePath(std::shared_ptr<AbcFunc> method)
    {
        auto path = GetPath(method);
        return path->namespaces;
    }
    std::string GetPackagePath(std::shared_ptr<AbcFunc> method)
    {
        auto path = GetPath(method);
        return path->package;
    }
    std::string GetModulePath(std::shared_ptr<AbcFunc> method)
    {
        auto path = GetPath(method);
        return path->module;
    }
    AbckitCoreFunction *GetAbckitCoreFunction(std::shared_ptr<AbcFunc> method)
    {
        return method->func;
    }

    std::set<std::shared_ptr<AbcFunc>> GetAnonymousFuncs(std::shared_ptr<AbcFunc> method)
    {
        return method->anonymousFuncs;
    }
    bool HasAnonymousFunc(std::shared_ptr<AbcFunc> method)
    {
        return method->anonymousFuncs.size() > 0;
    }
    AbcFuncType GetAbcFuncType(std::shared_ptr<AbcFunc> method)
    {
        return method->type;
    }

    MethodInspectApi mi_Impl = {
        GetMethodModuleNode,
        GetMethodNamespaceNode,
        GetMethodClassNode,
        GetPath,
        GetMethodName,
        GetClassName,
        GetNamespacePath,
        GetPackagePath,
        GetModulePath,
        GetAbckitCoreFunction,
        GetAnonymousFuncs,
        HasAnonymousFunc,
        GetAbcFuncType,
    };
};

MethodInspectApi const *MethodInspectApiImpl()
{
    return &abccontext::mi_Impl;
}